home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
editors
/
mjovesrc.zoo
/
jove.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-16
|
30KB
|
1,588 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
/* Contains the main loop initializations, and some system dependent
type things, e.g. putting terminal in CBREAK mode, etc. */
#include "jove.h"
#include "fp.h"
#include "termcap.h"
#include "ctype.h"
#include "chars.h"
#include "disp.h"
#include "re.h" /* for find_tag() */
#include "rec.h"
#ifdef IPROCS
# include "iproc.h"
#endif
#ifdef SCO
#undef TIOCGWINSZ
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
#ifdef MAC
# include "mac.h"
#else
# ifdef STDARGS
# include <stdarg.h>
# else
# include <varargs.h>
# endif
# include <stat.h>
#endif
#include <signal.h>
#include <errno.h>
#ifdef MSDOS
# include <process.h>
#endif /* MSDOS */
#ifndef MAC
# include <fcntl.h>
#endif
#ifdef MSDOS
private void break_off proto((void)),
break_rst proto((void));
#endif
#ifdef MAC
# define WINRESIZE 1
#else
# ifdef TIOCGWINSZ
# ifdef SIGWINCH
# define WINRESIZE 1
# endif
# endif
#endif
private void
DoKeys proto((bool firsttime));
#ifdef MSDOS
extern
#else
private
#endif
void
UnsetTerm proto((char *)),
do_sgtty proto((void));
/* Various tty state structures.
* Each is an array, subscripted by one of "OFF" or "ON".
*/
#ifdef UNIX
#include "ttystate.h"
# ifdef TIOCSLTC
struct ltchars ls[2];
# endif /* TIOCSLTC */
# ifdef TIOCGETC
struct tchars tc[2];
# endif
# ifdef PASS8 /* use pass8 instead of raw for meta-key */
private int lmword[2]; /* local mode word */
# endif
# ifdef BRLUNIX
struct sg_brl sg[2];
#endif
#ifdef TERMIO
struct termio sg[2];
#endif
#ifdef TERMIOS
struct termios sg[2];
#endif
#ifdef SGTTY
struct sgttyb sg[2];
#endif
# ifdef BIFF
private struct stat tt_stat; /* for biff */
# ifndef BSD4_2
private char *tt_name = NULL; /* name of the control tty */
extern char *ttyname(); /* for systems w/o fchmod ... */
# endif
private bool dw_biff = NO; /* whether or not to fotz at all */
# endif /* BIFF */
#endif /* UNIX */
bool errormsg;
char NullStr[] = "";
jmp_buf mainjmp;
#ifdef MSDOS
# define SIGHUP 99
#endif /* MSDOS */
/* finish() does not return, so it is funny that it returns a non-void
* result. This is because most systems claim that signal(2) deals
* with functions of type int (). ANSI changes this: the function
* type must be void (int). This bridge must soon be crossed.
*/
SIGRESULT
finish(code)
int code;
{
int save_errno = errno; /* Subtle, but necessary! */
static int Crashing = 0; /* we are in the middle of crashing */
bool CoreDump = (code != 0 && code != SIGHUP),
DelTmps = YES; /* Usually we delete them. */
if (code == SIGINT) {
char c;
#ifdef PIPEPROCS
int started;
#endif
#ifndef MENLO_JCL
(void) signal(code, finish);
#endif
f_mess("Abort (Type 'n' if you're not sure)? ");
#ifndef MSDOS
# ifdef PIPEPROCS
started = kbd_stop();
# endif
#ifdef SYSV
if (read(0, (UnivPtr) &c, (size_t) 1) != 1)
#endif
(void) read(0, (UnivPtr) &c, (size_t) 1);
# ifdef PIPEPROCS
if (started)
(void) kbd_strt();
# endif
#else /* MSDOS */
c = getrawinchar();
#endif /* MSDOS */
message(NullStr);
if ((c & 0377) != 'y') {
redisplay();
errno = save_errno;
SIGRETURN;
}
}
DisabledRedisplay = YES;
#ifndef MAC
UnsetTerm(NullStr);
#endif
#ifdef PIPEPROCS
kbd_kill(); /* kill the keyboard process */
#endif
#ifndef MSDOS
if (code != 0) {
if (!Crashing) {
Crashing = YES;
lsave();
SyncRec();
writef("JOVE CRASH!! (code %d): %s\n", code,
strerror(errno));
if (ModBufs(YES)) {
writef("Your buffers have been saved.\n");
writef("Use \"jove -r\" to have a look at them.\n");
DelTmps = NO; /* Don't delete anymore. */
} else
writef("You didn't lose any work.\n");
} else
writef("\r\nYou may have lost your work!\n");
}
#endif /* MSDOS */
flushscreen();
if (DelTmps) {
#ifdef PTYPROCS
(void) signal(SIGCHLD, SIG_IGN);
#endif
tmpremove();
#ifndef MSDOS
recremove();
#endif /* MSDOS */
}
#ifdef UNIX
if (CoreDump)
abort();
#ifdef PROFILING
exit(0);
#else
_exit(0);
#endif
#else /* !UNIX */
#ifdef MSDOS
break_rst(); /* restore previous ctrl-c handling */
#endif
exit(0);
#endif /* !UNIX */
/*NOTREACHED*/
}
private char smbuf[20],
*bp = smbuf;
private int nchars = 0;
private char peekbuf[10],
*peekp = peekbuf;
#if defined(SYSV) || defined(M_XENIX)
#define NONBLOCKINGREAD 1
private void
setblock(fd, on) /* turn blocking on or off */
register int fd;
bool on;
{
static int blockf, nonblockf;
static bool first = TRUE;
if (first) {
int flags;
first = FALSE;
if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
finish(SIGHUP);
blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
nonblockf = flags | O_NDELAY; /* make sure O_NDELAY is on */
}
if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
finish(SIGHUP);
}
#endif /* defined(SYSV) || defined(M_XENIX) */
private int
Peekc()
{
return peekp == peekbuf? EOF : *--peekp & 0377;
}
void
Ungetc(c)
int c;
{
if (peekp != &peekbuf[(sizeof peekbuf) - 1])
*peekp++ = c;
}
bool InputPending = NO;
char *Inputp = NULL;
#ifdef PTYPROCS
/* Warning! This code requires 32-bit ints. A thoroughly obscure mess --
ffs() as a three-line "for" loop. This is what you get for not
including ffs() in the libs. -- Doug
*/
#ifdef MiNT
int
ffs(int i)
{
int z;
for (z = 1; z <= (sizeof(int) * 8); z++)
if (i & ~(0xFFFFFFFF >> z))
return ((sizeof(int) * 8) - --z);
}
#endif
int
jgetchar()
{
long reads;
register int tmp,
nfds;
int c;
if (nchars <= 0) {
/* Get a character from the keyboard, first checking for
any input from a process. Handle that first, and then
deal with the terminal input. */
do {
do {
reads = global_fd;
nfds = select(32, &reads, (long *)NULL, (long *)NULL, (struct timeval *)NULL);
} while (nfds < 0 && errno == EINTR);
if (nfds == -1)
complain("\rerror in select %ld: %s", global_fd, strerror(errno));
else {
if (reads & 01) {
/* This is where I replaced read() with my own command to get characters
from the BIOS. This allowed me to implement all the Atari special keys.
Recent developments in MiNT have rendered all of this obsolete, and it
is one thing I will eventually replace. If you, the reader, decide to
undertake this yourself, please email a copy of your code to:
dstailey@leidecker.gsfc.nasa.gov -- Doug
*/
#ifdef MiNT
*smbuf = jgetkey();
nchars = 1;
#else
nchars = read(0, (UnivPtr) smbuf, sizeof(smbuf));
#endif MiNT
reads &= ~01;
nfds -= 1;
}
while (nfds--) {
tmp = ffs(reads) - 1;
read_proc(tmp);
reads &= ~(1L << tmp);
}
}
} while (nchars <= 0);
if (nchars <= 0)
finish(SIGHUP);
bp = smbuf;
InputPending = (nchars > 1);
}
if (((c = *bp) & 0200) && MetaKey) {
*bp = (c & CHARMASK);
return '\033';
}
nchars -= 1;
return *bp++ & 0377;
}
#else /* !PTYPROCS */
int
jgetchar()
{
register int c;
struct header {
int pid;
int nbytes;
} header;
normal:
if (nchars <= 0) {
bp = smbuf;
#ifdef MSDOS
*bp = getrawinchar();
nchars = 1;
#else /* !MSDOS */
# ifdef IPROCS
if (NumProcs > 0) {
for (;;) {
size_t n = f_readn(ProcInput, (char *) &header,
sizeof(header));
if (n != sizeof(header)) {
raw_complain("\r\nError reading kbd process, expected %d, got %d bytes\r\n", sizeof header, n);
finish(SIGHUP);
}
/* data is from the keyboard process */
if (header.pid == kbd_pid) {
nchars = f_readn(ProcInput, smbuf, header.nbytes);
if (nchars != header.nbytes) {
raw_complain("\r\nError reading kbd process, expected %d, got %d bytes.\r\n", header.nbytes, nchars);
finish(SIGHUP);
}
break;
}
read_proc(header.pid, header.nbytes);
if (NumProcs == 0) {